#ifndef _WX_TIMER_H_BASE_
#define _WX_TIMER_H_BASE_

#include "wx/defs.h"
#include "wx/object.h"
#include "wx/longlong.h"
#include "wx/event.h"
#include "wx/stopwatch.h"
#include "wx/window.h"

#define wxTIMER_CONTINUOUS false
#define wxTIMER_ONE_SHOT true

class wxTimerBase : public wxEvtHandler {
  public:
    wxTimerBase() { Init(); SetOwner( this ); }
    wxTimerBase( wxEvtHandler *owner, int timerid = wxID_ANY ) { Init(); SetOwner( owner, timerid ); }
    void SetOwner( wxEvtHandler *owner, int timerid = wxID_ANY ) {
      m_owner = owner;
      m_idTimer = timerid == wxID_ANY ? wxWindow::NewControlId() : timerid;
    }
    wxEvtHandler *GetOwner() const { return m_owner; }
    virtual ~wxTimerBase();
    virtual bool Start( int milliseconds = -1, bool oneShot = false );
    virtual void Stop() = 0;
    virtual void Notify();
    virtual bool IsRunning() const = 0;
    int GetId() const { return m_idTimer; }
    int GetInterval() const { return m_milli; }
    bool IsOneShot() const { return m_oneShot; }
  protected:
    void Init() { m_owner = NULL; m_idTimer = wxID_ANY; m_milli = 0; m_oneShot = false; }
    wxEvtHandler *m_owner;
    int m_idTimer;
    int m_milli;
    bool m_oneShot;
    DECLARE_NO_COPY_CLASS( wxTimerBase )
};

class wxTimer : public wxTimerBase {  // 时钟
  public:
    wxTimer() { Init(); }
    wxTimer( wxEvtHandler *owner, int id = -1 ) : wxTimerBase( owner, id ) { Init(); }
    virtual ~wxTimer();
    virtual bool Start( int millisecs = -1, bool oneShot = FALSE );
    virtual void Stop();
    virtual bool IsRunning() const { return m_tag != -1; }
  protected:
    void Init();
    int  m_tag;
  private:
    DECLARE_ABSTRACT_CLASS( wxTimer )
};

class wxTimerRunner {
  public:
    wxTimerRunner( wxTimer& timer ) : m_timer( timer ) { }
    wxTimerRunner( wxTimer& timer, int milli, bool oneShot = false )
      : m_timer( timer ) {
      m_timer.Start( milli, oneShot );
    }
    void Start( int milli, bool oneShot = false ) {
      m_timer.Start( milli, oneShot );
    }
    ~wxTimerRunner() {
      if( m_timer.IsRunning() ) {
        m_timer.Stop();
      }
    }
  private:
    wxTimer& m_timer;
    DECLARE_NO_COPY_CLASS( wxTimerRunner )
};

class wxTimerEvent : public wxEvent {
  public:
    wxTimerEvent( int timerid = 0, int interval = 0 ) : wxEvent( timerid ) {
      m_eventType = wxEVT_TIMER;
      m_interval = interval;
    }
    int GetInterval() const { return m_interval; }
    virtual wxEvent *Clone() const { return new wxTimerEvent( *this ); }
  private:
    int m_interval;
    DECLARE_DYNAMIC_CLASS_NO_ASSIGN( wxTimerEvent )
};

typedef void ( wxEvtHandler::*wxTimerEventFunction )( wxTimerEvent& );

#define wxTimerEventHandler(func) \
  (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxTimerEventFunction, &func)

#define EVT_TIMER(timerid, func) \
  wx__DECLARE_EVT1(wxEVT_TIMER, timerid, wxTimerEventHandler(func))

#endif
